import RemoteAccess from "../remote-access";
import ContentProvider from "../../api/content-provider";
// @ts-ignore
import axios from "axios";
import ContentNotExistException from "../../api/exception/content-not-exist-exception";
import assert = require("assert");

export default class RemoteAccessGitee implements RemoteAccess{
    private readonly owner: string;
    private readonly accessToken: string;
    private readonly repository: string;
    private readonly path: string;

    constructor(owner: string, repository: string, path: string, accessToken: string) {
        assert(owner && owner.trim() !== '')
        assert(path && owner.trim() !== '')
        assert(accessToken && accessToken.trim() !== '')
        this.owner = owner;
        this.repository = repository;
        this.path = path;
        this.accessToken = accessToken;
    }

    async getSha(): Promise<string>{
        const url = `https://gitee.com/api/v5/repos/${this.owner}/${this.repository}/contents/${this.path}?access_token=${this.accessToken}`;

        let response = undefined;
        try{
            response = await axios.get(url);
        }catch (e) {
            if(e.response.status === 404){
                return Promise.reject(new ContentNotExistException('仓库中不存在该文件:' + this.path));
            }
            return Promise.reject(e);
        }
        // @ts-ignore
        const data = response.data;
        if(!data.sha){
            return Promise.reject(new ContentNotExistException('仓库中不存在该文件:' + this.path));
        }
        return data.sha;
    }

    async getContent(): Promise<Buffer> {

        const url = `https://gitee.com/api/v5/repos/${this.owner}/${this.repository}/contents/${this.path}?access_token=${this.accessToken}`;

        let response = undefined;
        try {
            response = await axios.get(url);
        }catch (e){
            // @ts-ignore
            if(e.response.status === 404){
                return Promise.reject(new ContentNotExistException('仓库中不存在该文件:' + this.path));
            }
            return Promise.reject(e);
        }

        // @ts-ignore
        if(!response.data || !response.data.content){
            return Promise.reject(new ContentNotExistException('仓库中不存在该文件:' + this.path));
        }
        // @ts-ignore
        return Buffer.from(response.data.content, "base64");
    }


    async getLastModifiedTime(): Promise<Date> {
        const url = `https://gitee.com/api/v5/repos/${this.owner}/${this.repository}/commits?` +
            `access_token=${this.accessToken}&sha=master&path=${this.path}`;
        const response = await axios.get(url);
        let data = response.data;
        data = data.map(function (currentValue){
            return new Date(currentValue.commit.committer.date).getTime();
        }).sort().map(t => new Date(t));
        if(data.length == 0){
            return Promise.reject(new Error('无法获取Gitee仓库中书签的最后修改时间'));
        }
        return data[data.length-1];
    }


    async pushContent(contentProvider: ContentProvider):Promise<any> {
        const buffer = await contentProvider.getContent();
        const content = buffer.toString("base64");
        return await this.updateFile(content);
    }

    async updateFile(content){

        let sha = undefined;
        try {
            // @ts-ignore
            sha = await this.getSha();
        }catch (e){
            if(e instanceof ContentNotExistException){
                sha = undefined;
            }else {
                return Promise.reject(e);
            }
        }
        const data = {
            access_token: this.accessToken,
            content: content,
            message: '',
            sha: sha
        }
        if(sha){
            // gitee 仓库中已经存在相应的文件
            // 直接更新
            data.message = '更新书签内容';
            const url = `https://gitee.com/api/v5/repos/${this.owner}/${this.repository}/contents/${this.path}`
            return await axios.put(url, data)
        }

        // gitee仓库中不存在相应的文件
        // 所以需要创建对应的文件
        data.message = '创建书签文件';
        const url = `https://gitee.com/api/v5/repos/${this.owner}/${this.repository}/contents/${this.path}`;
        try{
            return await axios.post(url, data);
        }catch (e) {
            if(e.response.status === 404){
                return Promise.reject(new Error('创建远程书签失败，有可能是仓库未初始化.(' + e.message +')'))
            }else {
                return Promise.reject(e);
            }
        }

    }

    async update(buffer: Buffer): Promise<any> {
        return  await this.updateFile(buffer.toString("base64"));
    }

}
